#include "container.h"
namespace apollo
{
	namespace core
	{
		Container::Container(void)
		{
		}

		Container::~Container(void)
		{
			QList<Component*> list = components.values();
			foreach(Component* c, list)
			{
				//delete c->creator;
				delete c;
			}
			list.clear();
			while(disposer.isEmpty() == false)
			{
				QSharedPointer<Base> obj = disposer.pop();
				QSharedPointer<Starter> starter(obj.dynamicCast<Starter>());
				if(starter)
				{
					starter->stop();
				}

			}
		}

		QSharedPointer<Base> Container::resolve(const QString &key)
		{
			Component* compo =	 components.value(key, NULL);
			if(compo == NULL)
			{
				THROW_EXP(key + " component is not register.");
			}
			if(compo->object == NULL)
			{
				QMutexLocker lock(&compo->locker);
				if(compo->object == NULL)
				{
					compo->object = compo->creator(this);

					QSharedPointer<Starter> starter(compo->object.dynamicCast<Starter>());
					if(starter.isNull() == false)
					{
						starter->start(this);
					}

				}
			}
			return compo->object;
		}

		template<typename T>
		QSharedPointer<T> Container::resolve(const QString &key)
		{
			QSharedPointer<Base> obj = resolve(key);
			return obj.dynamicCast<T>();
		}

		void Container::registerCreator(const QString &key, Creator creator, bool lazy)
		{
			Component* compo =	 components.value(key, NULL);
			if(compo != NULL)
			{
				THROW_EXP(key + " component has been registered.");
			}
			compo = new Component();
			compo->key = key;
			components.insert(key, compo);
			compo->creator = creator;
			compo->lazy = lazy;
		}
		void Container::start()
		{
			QList<Component*> list = components.values();
			foreach(Component* c, list)
			{
				if(c->lazy == false)
				{
					resolve(c->key);
				}
			}
		}
	}
}